package chatroom;

import java.net.*;
import java.io.*;
import java.util.*;


public class Client {

    // for I/O
    private ObjectInputStream sInput;		
    private ObjectOutputStream sOutput;		
    private Socket socket;
     
    public ClientGame mainGame;
   
    public String server, username, username2;
    private int port;
    public boolean onGame;
    private ChatMessage cmSend;
    public String myMarks, myMarks2;
    public String myExp,myExp2;
    public boolean isWin;

    Client(String server, int port, String username) {
      
        this(server, port, username, null);
    }

   
    Client(String server, int port, String username, ClientGame mg) {
        this.server = server;
        this.port = port;
        this.username = username;
           
        this.mainGame = mg;
        onGame = false;
        myMarks = myMarks2 = username2 = myExp = myExp2 = "";
        isWin = false;

    }

   
    public boolean start() {
       
        try {
            socket = new Socket(server, port);
        } 
        catch (Exception ec) {
            if (mainGame != null) {
                display("Server has close the connection: " + ec);
            } else {
                System.out.println("Server has close the connection: " + ec);
            }
            return false;
        }

        String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
        display(msg);


       
        try {
            sInput = new ObjectInputStream(socket.getInputStream());
            sOutput = new ObjectOutputStream(socket.getOutputStream());
        } catch (IOException eIO) {
            if (mainGame != null) {
                display("Server has close the connection: " + eIO);
            } else {
                System.out.println("Server has close the connection: " + eIO);
            }

            return false;
        }

       // Lang nge mes tung Server
        new ListenFromServer().start();
        
        try {
            sOutput.writeObject(username);
        } catch (IOException eIO) {
            display("Server has close the connection: " + eIO);
            disconnect();
            return false;
        }
      
        return true;
    }

   // hien thi len message len clientGame
    public void display(String msg) {
        if (mainGame != null) {
            mainGame.appendStatus(msg);
        } else {
            System.out.println(msg);
        }
    }

    // gui message den server
    public void sendMessage(ChatMessage msg) {
        try {
            sOutput.writeObject(msg);
        } catch (IOException e) {
            if (mainGame != null) {
                display("Server đã đóng kết nối " + e);
            } else {
                System.out.println("Server đã đóng kết nối: " + e);
            }
        }
    }

   // khi client k ket noi dc
    private void disconnect() {
        try {
            if (sInput != null) {
                sInput.close();
            }
        } catch (Exception e) {
        } // not much else I can do
        try {
            if (sOutput != null) {
                sOutput.close();
            }
        } catch (Exception e) {
        } // not much else I can do
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (Exception e) {
        } 
    }


    public static void main(String[] args) {
       
        int portNumber = 1500;
        String serverAddress = "localhost";
        String userName = "Hello";


        // tao client moi
        Client client = new Client(serverAddress, portNumber, userName);      
        
        if (!client.start()) {
            return;
        }        

        // done disconnect
        client.disconnect();
    }

    // Lang nge Server
    class ListenFromServer extends Thread {

        public void run() {
            while (true) {
                try {

                    ChatMessage cm = (ChatMessage) sInput.readObject();
                    String msg = cm.getMessage();
                    switch (cm.getType()) {
                        case ChatMessage.MESSAGE:
                            display(msg);
                            break;
                        case ChatMessage.LOGOUT:                            
                            if (msg.equals(username2)){
                                mainGame.setNoti("Đối phương đã thoát nên bạn đã giành chiến thắng...");                               
                                mainGame.setPlayAgain();                                
                            } 
                            display(msg + " đã thoát khỏi room ");
                            mainGame.block = true;
                            break;
                        case ChatMessage.JOINGAME:
                            display(msg);                            
                            if (msg.equals("Start Game:")) {
                                onGame = true;
                                break;
                            } 
                            if (onGame && username2.equals("")) {
                                if (msg.equals("1) " + username + " : X")) {
                                    myMarks = "X";
                                    myMarks2 = "O";
                                    break;
                                } else {
                                    if (myMarks.equals("") && myMarks.equals("")) {
                                        myMarks = "O";
                                        myMarks2 = "X";
                                    }
                                    username2 = msg.substring(3,msg.length() - 4);
                                }
                                if (myMarks2.equals("O")) {
                                    username2 = msg.substring(3, msg.length() - 4);

                                }
                                if (!username.equals("") && !username2.equals("") && !myMarks.equals("") && !myMarks2.equals("")) {
                                    mainGame.setGame(username, username2, myMarks, myMarks2);
                                    mainGame.setIsMyState(myMarks);
                                    if (myMarks.equals("X")) {
                                        mainGame.setNoti("Bạn đánh trước... (X)");
                                        mainGame.block = false;
                                    } else if (myMarks.equals("O")){
                                        mainGame.setNoti("Đợi " + username2 + " đang đánh... ");
                                        mainGame.block = true;
                                    }
                                }
                                if (myMarks.equals("") && onGame == false) {
                                    mainGame.setNoti("Đang đợi Server xử lý...");
                                }
                                break;
                            }

                            break;
                        case ChatMessage.MOVES:
//                           Paint move (Ex: Move X : 10,12)
                            String row = "?";
                            String col = "?";
                            if (msg.substring(5, 6).equals("X")) {
                                if (msg.substring(10, 11).equals(",")) {
                                    row = msg.substring(9, 10);
                                    if (msg.length() == 12) {
                                        col = msg.substring(11, 12);
                                    } else if (msg.length() == 13) {
                                        col = msg.substring(11, 13);
                                    }
                                } else if (msg.substring(11, 12).equals(",")) {
                                    row = msg.substring(9, 11);
                                    if (msg.length() == 13) {
                                        col = msg.substring(12, 13);
                                    } else if (msg.length() == 14) {
                                        col = msg.substring(12, 14);
                                    }
                                }
                                mainGame.setIcon(Integer.parseInt(row), Integer.parseInt(col), "X");
                            }
                            if (msg.substring(5, 6).equals("O")) {
                                if (msg.substring(10, 11).equals(",")) {
                                    row = msg.substring(9, 10);
                                    if (msg.length() == 12) {
                                        col = msg.substring(11, 12);
                                    } else if (msg.length() == 13) {
                                        col = msg.substring(11, 13);
                                    }
                                } else if (msg.substring(11, 12).equals(",")) {
                                    row = msg.substring(9, 11);
                                    if (msg.length() == 13) {
                                        col = msg.substring(12, 13);
                                    } else if (msg.length() == 14) {
                                        col = msg.substring(12, 14);
                                    }
                                }
                                mainGame.setIcon(Integer.parseInt(row), Integer.parseInt(col), "O");
                            }

                            // block game
                            if (!msg.substring(5, 6).equals(myMarks) && !myMarks.equals("")) {
                                mainGame.setBlock(false);
                                mainGame.setNoti("Đến lượt bạn đánh .... (" +myMarks + ")");
                            } else {
                                mainGame.setBlock(true);
                            }
                            break;
                        case ChatMessage.WIN:
                            isWin = true;
                            mainGame.setVisiblePlayAgain();
                            mainGame.setNoti("Đã thúc ván đấu và chiến thắng là Client cầm " + msg.substring(0, 1));  
                            if (msg.substring(0, 1).equals(myMarks)) {
                                mainGame.setNoti("Chúc mừng " + username + " đã chiến thắng .... ");

                            }
                            if (msg.substring(0, 1).equals(myMarks2)) {
                                mainGame.setNoti("Bạn thua " + username2 + " rồi .... ");
                            }                         
                                                    
                            break;
                        case ChatMessage.AGAIN:                           
                            if (!myMarks.equals("")){
                                mainGame.setNoti( "PLAY AGAIN !!! \n Cầm O được đánh trước... " );
                                   isWin = false;
                            }                            
                            mainGame.setPlayAgain();
                            display(msg);
                            break;
                        case ChatMessage.ISWRITE:
                            if (msg.equals(username)){
                                 mainGame.setIsWrite("...    ");
                            } else{
                            mainGame.setIsWrite(msg +" đang viết....    ");
                         }                            
                            break;
                         case ChatMessage.ISWRITESTOP:
                            if (msg.endsWith(username)){
                                 mainGame.setIsWrite("...   ");
                            } else{
                                mainGame.setIsWrite("??    ");
                             }                            
                            break;
                         case ChatMessage.FULLGAME: 
                            if (myMarks.equals("")){
                                mainGame.setBlock(true);
                                mainGame.setNoti("Bạn đang vào Room với chế độ quan sát");
                                cmSend = new ChatMessage(ChatMessage.LOADGAME, "");
                                sendMessage(cmSend);
                            } 
                             break;
                         case ChatMessage.LOADGAME:
                             // Load map co cho client quan sat VD: X:(1,1)                            
                             if (myMarks.equals("")){  
                                 System.out.print(msg);
                                 if (msg.substring(4,5).equals(",")){ 
                                     System.out.println(" ---  " + msg.substring(3,4) +"," +msg.substring(5,msg.length()-1));
                                     int roww = Integer.parseInt(msg.substring(3,4));
                                     int colw = Integer.parseInt(msg.substring(5,msg.length()-1));
                                     mainGame.setIcon(roww, colw, msg.substring(0,1));                                    
                                 } else if (msg.substring(5,6).equals(",")){
                                     System.out.println(" +++  " + msg.substring(3,5) +"," +msg.substring(6,msg.length()-1));
                                     int roww = Integer.parseInt(msg.substring(3,5));
                                     int colw = Integer.parseInt(msg.substring(6,msg.length()-1));
                                     mainGame.setIcon(roww, colw, msg.substring(0,1));                                     
                                 }
                             }
                             break;
                        case ChatMessage.EXP:                            
                            if (onGame){                               
                                if (msg.substring(0,username.length() + 3 ).equals(username+" : ")){
                                    myExp = msg.substring(username.length()+3,msg.length());                                   
                                }                                
                                if (msg.substring(0, username2.length()+3).equals(username2+" : ")) {
                                    myExp2 = msg.substring(username2.length() + 3, msg.length());
                                }
                                if (!myExp.equals("") && !myExp2.equals("")) {
                                    mainGame.setExp(myExp, myExp2);
                                }
                            }
                            break;
                    }
                   

                } catch (IOException e) {
                    if (mainGame != null) {
                        display("Server đã đóng kết nối: " + e);
                    } else {
                        System.out.println("Server đã đóng kết nối: " + e);
                    }                  
                    break;
                } 
                catch (ClassNotFoundException e2) {
                }
            }
        }

        void writeDisplay(String msg) {
            if (mainGame == null) {
                System.out.println(msg);
                System.out.print("> ");
            } else {
                mainGame.appendStatus(msg);
            }
        }
    }
}
